简体   繁体   English

触发器和锁存器推断困境

[英]Flip-flop and latch inferring dilemma

Could someone explain to me why a latch would be inferred instead of a flip-flop? 有人可以向我解释为什么要推断出一个锁存器而不是一个触发器吗?

always_ff @ (posedge clk, negedge rst) 
begin
  if (!rst)
    a <= '0;
end

Shouldn't the fact that the always block is sensitive to a signal edge be enough to infer a flip-flop. 总块对信号沿敏感的事实不应足以推断出触发器。 In this case when a negative edge of reset is triggered a gets 0, else it keeps former value. 在这种情况下,当触发复位的下降沿时,a将变为0,否则它将保持先前的值。

This question comes from the selected best answer from this stackoverflow question: 这个问题来自这个stackoverflow问题的最佳选择:
System Verilog always_latch vs. always_ff 系统Verilog always_latch与always_ff

=========================================================================== ================================================== ========================

I will share here what I found out so far. 我将在这里分享我到目前为止的发现。 The reason why this synthesizes to a latch, instead of a flip-flop is because on the right side of the assignment is a CONSTANT. 之所以将其合成为锁存器而不是触发器的原因是,在分配的右侧是一个常量。 When this is the case the behavior of a latch and a flip-flop are EQUIVALENT, because it does not matter whether it catches the input value on a signal edge (flip-flop) or while input latching is enabled (latch) as the input does not change . 在这种情况下,锁存器和触发器的行为是等效的,因为无论是在信号沿捕获触发器值(触发器)还是在启用输入锁存器(锁存器)作为输入时,它都无关紧要不会改变 So the synthesis tool chooses the element that takes less resources, ie the latch. 因此,综合工具选择占用较少资源的元素,即锁存器。

On the other hand, if on the right side of the assignment there was a VARIABLE, the synthesis would have to infer a flip-flop, because it would matter whether the input is sampled on an edge (flip-flop) or during input latching is enabled (latch), meaning the two logic elements are NOT EQUIVALENT . 另一方面,如果在赋值的右侧有一个VARIABLE,则综合必须推断出触发器, 因为输入是在边沿(触发器)还是在输入锁存期间采样都很重要启用(闩锁),这意味着两个逻辑元素不相等

Here is an example. 这是一个例子。 First two always blocks will synthesize to a latch (in Quartus 14), which is OK, as they are equivalent, because of a constant. 前两个Always块将合成为一个锁存器(在Quartus 14中),这是可以的,因为它们相等,因为一个常数。 But, the 3. and the 4. always block will also be synthesized into a latch, which is not the intended behavior and these blocks are not equivalent! 但是,3.和4. Always块也将被合成为锁存器,这不是预期的行为,并且这些块不相等! The 3. block will give a warning, while the 4. one won't. 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

To me this behavior is not correct, as I specifically said I want a flip-flop (with edge triggering). 对我来说,这种行为是不正确的,正如我专门说的,我想要一个触发器(具有边沿触发功能)。 It's not even that the coding is ambiguous, always blocks 3. and 4. are clearly different, as can be seen in this waveform from the above simulation: 从上面的模拟中的波形可以看出,编码甚至不是模棱两可的,总是块3和块4明显不同。

在此处输入图片说明

Block 3. (tb_y) behaves like a asynchronous flip-flop and block 4. (tb_z) behaves like a latch . 块3(tb_y)的行为类似于异步触发器 ,块4(tb_z)的行为类似于闩锁 But the synthesis tool infers a latch in both cases . 但是综合工具会在两种情况下推断出一个闩锁

If someone can shed some light on this or comment the code or the waveform, it would be much appreciated. 如果有人可以对此有所了解或注释代码或波形,将不胜感激。

A synthesiser will infer a latch because this code behaves like a latch . 合成器将推断出一个闩锁,因为此代码的行为类似于闩锁 It does not behave like a flip-flop. 它的行为不像触发器。 It's as simple as that. 就这么简单。

Think about how this code behaves: initially the value of a will be 'x . 考虑一下此代码的行为方式:最初, a的值为'x When rst is asserted low then a will become '0 . rst断言为低电平时, a将变为'0 a will then remain at '0 forever. 然后a将永远保持为'0 The state of a therefore depends not only on the current state of the inputs, but also on the past state. 因此, a的状态不仅取决于输入的当前状态,还取决于过去的状态。 Therefore, we have sequential logic , not combinational logic . 因此,我们有顺序逻辑 ,而不是组合逻辑 Flip-flops change state on a clock edge; 触发器在时钟沿改变状态; a does not. a没有。 The fact that the always block is sensitive to a signal edge is irrelevant. 总块对信号沿敏感的事实是无关紧要的。 This just means that the code inside is executed on that signal edge - the positive edge of clk . 这仅表示内部代码在该信号沿( clk上升沿)执行。 But when that occurs, nothing happens , so this code behaves like a latch. 但是,当这种情况发生时, 什么也没有发生 ,因此此代码的行为就像闩锁一样。

Because you haven't specified what happens at posedge of the clock. 因为您尚未指定时钟的时机会发生什么。 It is as if a does not depend on clk or its posedge at all. 好像a完全不依赖clk或它的姿势。 All your description says is that a is set to 0 when rst=0 . 所有你的描述说的是, a被设置为0时, rst=0 Moreover, it says (implicitly) that a keeps its previous value in all other cases. 而且,它(暗含)说a在所有其他情况下都保持其先前的值。 This can be implemented by a latch. 这可以通过锁存器来实现。

Notice that just because you have @posedge of clk does not mean every variable inside that block will be synthesized as a flop. 注意,仅仅因为您拥有@posedge的clk并不意味着该块内的每个变量都将被合成为翻牌。 You also need a non-blocking assignment to a when the block is activated at posedge of clk. 您还需要非阻塞分配到a块时,在CLK的posedge激活。 See here . 这里

If you insist on having a flop to implement the same functionality, you can try this: 如果您坚持要求触发器实现相同的功能,则可以尝试以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM