Verilog 在if条件下,当else语句缺失时,推断出的闩锁是什么,以及如何创建闩锁。有人能简单解释一下吗?
我试图找出推断出的锁存器以及内部需要它的原因,但我找不到任何足够详细的资源。当组合逻辑的输出具有未定义的状态时,会推断出锁存器,即它必须保持其先前的值 组合逻辑没有任何保持状态的触发器,因此输出应始终由输入定义 一个简单的例子可能是:Verilog 在if条件下,当else语句缺失时,推断出的闩锁是什么,以及如何创建闩锁。有人能简单解释一下吗?,verilog,Verilog,我试图找出推断出的锁存器以及内部需要它的原因,但我找不到任何足够详细的资源。当组合逻辑的输出具有未定义的状态时,会推断出锁存器,即它必须保持其先前的值 组合逻辑没有任何保持状态的触发器,因此输出应始终由输入定义 一个简单的例子可能是: always @* begin if (a == 1'b1) begin b = x|y|z; end end 当a==1'b0时,b是什么b未被重写,因此它将保留其值。一个没有国家概念的东西怎么能保持它的价值呢。您必须通过推断闩锁来引入状态。
always @* begin
if (a == 1'b1) begin
b = x|y|z;
end
end
当a==1'b0
时,b
是什么<代码>b未被重写,因此它将保留其值。一个没有国家概念的东西怎么能保持它的价值呢。您必须通过推断闩锁来引入状态。这通常是一件非常糟糕的事情
您可以暗示锁存并小心计时等,但推断出的锁存通常来自错误代码。在组合块内推断出锁存,其中网络未分配给已知值。将网络分配给自身仍将推断闩锁。还可以通过灵敏度列表和反馈回路中的缺失信号推断锁存 在Verilog/SystemVerilog中推断预期闩锁的正确方法是:
/* Verilog */ //// /* SystemVerilog */
always @* //// always_latch
begin //// begin
if (en) q = d; //// if (en) q = d;
end //// end
意外推断闩锁的方式:
- 灵敏度列表缺少信号(这就是为什么应使用
):@*
- 缺失条件:
always @* begin case(in[1:0]) 2'b00: out = 1'b0; 2'b01: out = 1'b1; 2'b10: out = 1'b1; // inferred latch "out" :: missing condition 2'b11/default endcase end always @* begin next0 = flop0; next1 = flop1; // inferred latch "next2" :: missing initial condition next3 = flop3; case(a[2:0]) 3'b001: next0 = in; 3'b010: if(b) next1 = in; 3'b100: if(c) next2 = in; default: if(!b&&!c) next3 = in; endcase end
- 反馈回路:
assign out = en ? in : out; // inferred latch "out" :: feedback to mux assign a = en ? z : c; // ... any amount of code between ... assign z = en ? a : y; // inferred latch "a" :: feedback chain
- 反馈回路可以遍历层次结构和设计
- 使预期的插销简单且易于识别:
- 用尽可能少的组合逻辑将预期的锁存器放在它们自己的始终块中;理想情况下,将锁存器的组合逻辑放在其单独的always块中。尽可能明确并确定预期的闩锁。使用注释、标签,并在可能的情况下使用SystemVerilog
always\u-latch
- 用尽可能少的组合逻辑将预期的锁存器放在它们自己的始终块中;理想情况下,将锁存器的组合逻辑放在其单独的always块中。尽可能明确并确定预期的闩锁。使用注释、标签,并在可能的情况下使用SystemVerilog
- 所有组合逻辑块都需要使用
或SystemVerilog的始终@*
始终梳定义
- 确保在组合逻辑块中分配的所有变量都具有初始或默认分配。
语句应具有case
默认条件
语句应具有相应的if
else
- 当组合逻辑块分配多个变量时,在块的开头(在任何
或案例
之前)给每个变量一个初始值案例
- 知道输入来自何处,输出将流向何处。
- 组合逻辑的输入应为触发器或组合逻辑的输出应为触发器
- 进行代码审查,使用linting工具和逻辑等价性检查工具。
- 代码审阅要求审阅者知道闩锁可以隐藏在哪里
- 使用SystemVerilog的
可以通过linting和逻辑等价性检查工具帮助识别推断的锁存always_comb
最坏的情况是,将所有逻辑放在同步块中。所有推断的锁存器都将成为推断的触发器。这通常是一个坏主意,因为它会不必要地增加门计数,创建更多路由,并影响定时。闩锁仅使用组合always块生成。顺序逻辑永远不会生成锁存器
有关详细信息,请阅读也许您可以包含指向您已经查看过的位置的链接,这样人们就不会建议您已经尝试过的内容。我认为应该添加
always\u latch
,作为在SystemVerilog@Morgan,你的建议已添加到我的答案中
assign out = en ? in : out; // inferred latch "out" :: feedback to mux
assign a = en ? z : c;
// ... any amount of code between ...
assign z = en ? a : y; // inferred latch "a" :: feedback chain