【问题标题】:Synchronous reset design in fpga as the limiting factor for timing constraintsfpga 中的同步复位设计作为时序约束的限制因素
【发布时间】:2013-05-31 19:23:22
【问题描述】:

我有一个利用同步复位的 fpga 设计(由于其他地方讨论的原因,我更喜欢同步复位而不是异步)。我在设计中有四个不同的时钟域,我使用一个按钮来生成我的复位信号,这当然与所有东西完全异步(保存我的手指)。我在四个时钟域中的每一个中对按钮信号进行去抖动处理,以从单个源为四个域生成同步复位。我的去抖模块基本上计算了复位按钮被断言的 N 个时钟周期。如果在置位复位的情况下经过了 N 个以上的周期,那么我会生成我的复位信号(此模块的代码粘贴在下面)。

第一个问题——有没有比这种方法更好的生成重置的方法?

第二个(更有趣的问题):当我查看时序报告(使用 xilinx 工具)时,我发现限制信号始终都与复位相关。例如,限制路径是从复位发生器(去抖动器)到某个状态机的状态寄存器。复位信号非常高扇出(它们触及各自时钟域中的所有内容)。虽然我的速度受到重置的限制,但我有点惊讶。我发现我的速度仅限于 8.5 nS,其中约 50% 是路由,其中​​约 50% 是逻辑。关于如何更好地做到这一点的任何建议?您如何处理 fpga 设计中的同步复位生成?

这是重置生成的代码。请注意,信号复位信号类似于去抖输出(例如,当我实例化模块时,debounced 输出是该特定时钟域的复位)。

module button_debouncer(/*AUTOARG*/
   // Outputs
   debounced,
   // Inputs
   clk, button
   );
   /* Parameters */
   parameter WIDTH = 1;
   parameter NUM_CLKS_HIGH = 12000000;
   parameter log2_NUM_CLKS = 24;

   /* Inputs */
   input clk;
   input [WIDTH-1:0] button;

   /* Outputs */
   output [WIDTH-1:0] debounced;

   /* Regs and Wires */
   reg [WIDTH-1:0]    b1, b2;
   reg [log2_NUM_CLKS-1:0] counter;

   /* Synched to clock domain */
   always @(posedge clk) begin
      b1 <= button;
      b2 <= b1;
   end

   /* Debounce the button */
   always @(posedge clk) begin
      if(~b2)
    counter <= 0;
      else if(counter < {log2_NUM_CLKS{1'b1}})
    counter <= counter + 1;
   end

   /* Assign the output */
   //wire [WIDTH-1:0] debounced = counter > NUM_CLKS_HIGH;
   reg [WIDTH-1:0] debounced;

   always @(posedge clk) begin
      debounced <= counter > NUM_CLKS_HIGH;
   end

endmodule //button_debouncer

【问题讨论】:

  • 我原来的去抖动器好像没有注册输出(原来的版本被注释掉了)。通过注册输出,我(不出所料)能够提高性能,使复位信号不再是限制路径。也就是说,重置策略的一般问题仍然存在。谢谢!
  • 您的 fpga 真的需要重置吗? FPGA 可以使用初始状态进行编程,因此如果您只需要一个干净的起点,您可以使用initial,然后为您自己节省重置网络的面积/时序费用。
  • 感谢@Tim 的评论。是的,我确实需要重置。谢谢。

标签: verilog fpga xilinx


【解决方案1】:

在使用重置时提高时序分数的一个非常好的方法是限制最大扇出。然后,这些工具将缓冲信号,以便没有一个 lut 试图路由并用于驱动每个寄存器。这可以通过这种方式完成:

(* max_fanout = <arbitrary_value> *) 
wire reset; 

所以我们这里有一个由 vivado 合成器工具使用的约束(或者如果您仍在使用 ISE,那么该工具)。另外,如果应该注意,这只影响下一个网络的声明,因此在此之前或之后声明的其他网络(wires、regs、ext)不受影响。

在 xilinx 的网站上有一个很好的约束用户指南。您可能还想研究其他一些,它们是:IBUF 或 BUFG。

【讨论】:

  • 感谢您的信息。这似乎是一个合理的方法。我已经启用了寄存器复制(我认为实际上应该完全按照您的建议来满足时序要求)。我想知道在架构上是否有比我所做的更聪明的事情要做。只是为了澄清-使用您的方案,层次结构中较低的模块是否会从高于它的模块中重置?例如。每个模块应该使用这样的扇出约束还是只使用几个更高级别的约束?
  • 重置来自顶层模块,然后扇出到所有其他模块和其他较低级别的模块。最大扇出限制通过,因为它由相同的 reg 或输入驱动。
【解决方案2】:

您不需要四个去抖动器实例。在您的主时钟上安装一个去抖动器,然后使用三个亚稳态滤波器将其输出同步到其他三个域。

此外,当您分发重置时,您应该使用 Cliff Cummings 所说的“同步重置分发树”。查看他的网站以获取有关这方面的一些论文。

【讨论】:

  • 这是作为评论还是答案?
  • 他说他正在四个不同的时钟域中对按钮信号进行去抖动,并询问是否有更好的方法来做到这一点。我假设他在每个域中都实例化了一个去抖动器。这将是相当浪费的,因为您可以在任何域中对其进行去抖动,然后将信号重新同步到其他域,而这比 24 位计数器/比较器要少得多。
猜你喜欢
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
相关资源
最近更新 更多