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