我试图找出推断的锁存器以及内部需要它的原因,但我找不到任何具有足够细节的资源。
答案 0 :(得分:15)
在组合块内推断出锁存器,其中网络未分配给已知值。为自己分配一个网仍然会推断一个锁存器。锁存器也可以通过缺失信号来形成灵敏度列表和反馈回路。
在Verilog / SystemVerilog中推断预期锁存器的正确方法是:
/* Verilog */ //// /* SystemVerilog */
always @* //// always_latch
begin //// begin
if (en) q = d; //// if (en) q = d;
end //// end
敏感度列表中缺少信号(这就是为什么应该使用@*
):
always @(a or b) // inferred latch :: "c" missing for the sensitivity list.
begin
out = a + b + c;
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_latch
。always @*
或SystemVerilog的always_comb
进行定义。case
语句应具有default
条件。if
语句应具有相应的else
。case
或if
之前)给每个变量一个初始值。always_comb
可以帮助识别带有linting和逻辑等效检查工具的推断锁存器。最糟糕的情况是,将所有逻辑放在同步块中。所有推断的锁存器都是推断的触发器。这通常是一个坏主意,因为它可能会不必要地增加门数,创建更多路由并影响时序。
答案 1 :(得分:2)
当组合逻辑的输出具有未定义状态时,推断出锁存器,即它必须保持其先前的值。
组合逻辑没有任何触发器来保持状态,因此输出应始终由输入定义。
一个简短的例子可能是:
always @* begin
if (a == 1'b1) begin
b = x|y|z;
end
end
b
时的a == 1'b0
是什么。 b
没有被覆盖,所以它会保持其价值。当某种东西没有国家概念时,它怎么能保持其价值。你必须通过推断一个锁存器来介绍状态。这通常是一件非常糟糕的事情。
你可以暗示锁存器并注意时序等,但推断的锁存器名义上来自有缺陷的代码。
答案 2 :(得分:2)
仅使用组合始终块生成锁存器。顺序逻辑永远不会生成锁存器。
有关更多信息,请参阅how transparent latches are created and how to avoid inferring latches