有人可以向我解释为什么会推断出闩锁而不是触发器吗?
always_ff @ (posedge clk, negedge rst)
begin
if (!rst)
a <= '0;
end
总是块对信号边缘敏感的事实是否足以推断触发器。在这种情况下,当触发复位的下降沿时,a 为 0,否则保持以前的值。
这个问题来自这个stackoverflow问题的选定最佳答案:
System Verilog always_latch vs. always_ff
==================================================== ==========================
我将在这里分享我到目前为止发现的内容。之所以合成到锁存器而不是触发器,是因为分配的右侧是一个常数。在这种情况下,锁存器和触发器的行为是等效的,因为它是否在信号边沿(触发器)上捕获输入值或在输入锁存启用时(锁存器)作为输入都没有关系不改变。所以综合工具选择占用资源较少的元素,即锁存器。
另一方面,如果在分配的右侧有一个 VARIABLE,那么综合将不得不推断一个触发器,因为输入是在边沿(触发器)上采样还是在输入锁存期间采样很重要启用(锁存器),这意味着两个逻辑元素不相等。
这是一个例子。前两个 always 块将合成到一个锁存器(在 Quartus 14 中),这没关系,因为它们是等价的,因为它们是一个常数。但是,3. 和 4. always 块也将被合成到一个锁存器中,这不是预期的行为,并且这些块不等价!3. 块会发出警告,而 4. 不会。
module ff_latch(
input logic clk,
input logic nrst,
input logic a,
output logic t, x, y, z
);
always_ff @(posedge clk, negedge nrst)
begin
if (!nrst)
t <= 0;
end
always_latch
begin
if (!nrst)
x <= 0;
end
always_ff @(posedge clk, negedge nrst)
begin
if (!nrst)
y <= a;
end
always_latch
begin
if (!nrst)
z <= a;
end
endmodule: ff_latch
对我来说,这种行为是不正确的,因为我特别说过我想要一个触发器(带有边沿触发)。甚至不是编码是模棱两可的,总是块 3. 和 4. 明显不同,从上面的模拟波形中可以看出:
块 3. (tb_y) 的行为类似于异步触发器,块 4. (tb_z) 的行为类似于锁存器。但综合工具在这两种情况下都会推断出一个闩锁。
如果有人可以对此有所了解或评论代码或波形,将不胜感激。