有人能给我解释一下为什么要推断锁锁而不是触发器吗?
always_ff @ (posedge clk, negedge rst)
begin
if (!rst)
a <= '0;
end
不应该总是块对信号边缘敏感这一事实不足以推断触发器。在这种情况下,当重置的负边缘被触发为gets 0时,它将保留以前的值。
此问题来自于从堆栈溢出问题中选择的最佳答案:
===========================================================================
我将在这里分享我到目前为止发现的情况。之所以合成锁存,而不是触发器,是因为在分配的右边是一个常量。在这种情况下,锁存和触发器的行为是等价的,因为它是在信号边缘(触发器)捕获输入值,还是当输入锁存启用时(锁存)不改变,这并不重要。因此,综合工具选择占用资源较少的元素,即锁存器。
另一方面,如果在赋值的右边有一个变量,那么综合就必须推断一个触发器,,因为输入是在边缘(触发器)上采样还是在输入锁存(锁存)启用期间(锁存)是重要的,这意味着这两个逻辑元素不是等效的。
下面是一个例子。前两个总是块将合成一个闩锁(在Quartus 14),这是好的,因为他们是等价的,因为一个常数。但是,3.和4.始终块也将被合成为锁存器,这不是预期的行为,而且这些块不是等效的!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)的行为类似于锁存。,但是合成工具在这两种情况下都推断出一个锁存器()。
如果有人能说明这一点,或评论的代码或波形,这将是非常感谢。
发布于 2016-06-01 14:40:53
合成器将推断出锁存器,因为这段代码的行为类似锁存器。它的行为不像触发器。事情就是这么简单。
考虑一下这段代码的行为:最初,a
的值是'x
。当rst
被断言为低时,a
就会变成'0
。然后,a
将永远留在'0
。因此,a
的状态不仅取决于输入的当前状态,还取决于过去的状态。因此,我们有顺序逻辑,而不是组合逻辑。触发器在时钟边缘改变状态;a
不改变状态。始终块对信号边缘敏感这一事实与此无关。这仅仅意味着内部的代码在信号边缘执行-- clk
的正边缘。但是当这种情况发生时,什么都不会发生,所以这段代码的行为就像一个闩锁。
发布于 2016-06-01 23:49:51
因为你还没有说明在时钟的前部会发生什么。这就好像a
完全不依赖于clk
或它的后置。您所描述的是,当a
设置为0
时,rst=0
会被设置为rst=0
。此外,它还(隐式地)表示,在所有其他情况下,a
都保留其先前的值。这可以通过锁存来实现。
请注意,仅仅因为您拥有@posedge of clk
,并不意味着该块中的每个变量都将被合成为触发器。当块在clk的边缘被激活时,您还需要向a
分配非阻塞赋值。见here。
如果您坚持要失败才能实现相同的功能,您可以尝试如下:
always_ff @ (posedge clk or negedge rst)
begin
if (!rst)
a <= '0;
else
a <= a; //Here, we are specifying what happens @posedge of clk
end
https://stackoverflow.com/questions/37571416
复制相似问题