什么是推断锁存器以及如何在缺少其他语句时创建它如果condition.can任何人简要解释?

时间:2014-03-17 16:07:44

标签: verilog

我试图找出推断的锁存器以及内部需要它的原因,但我找不到任何具有足够细节的资源。

3 个答案:

答案 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块中。明确并识别预期的锁存器。使用注释,标签,如果可能,请使用SystemVerilog always_latch
  • 所有组合逻辑块需要使用always @*或SystemVerilog的always_comb进行定义。
  • 确保在组合逻辑块中分配的所有变量都具有初始或默认分配。
    • case语句应具有default条件。
    • if语句应具有相应的else
    • 当组合逻辑块分配许多变量时,在块的开头(在任何caseif之前)给每个变量一个初始值。
  • 了解输入的来源以及输出的位置。
    • 组合逻辑的输入应该是触发器输出组合逻辑应该是触发器。
  • 执行代码审查,使用linting工具和逻辑等效检查工具。
    • 代码审查要求审核人员知道锁存器可以隐藏的位置。
    • 使用SystemVerilog的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