【问题标题】:better way of coding a D flip-flop编码 D 触发器的更好方法
【发布时间】:2012-06-13 03:10:59
【问题描述】:

最近在verilog中看到一些D触发器RTL代码是这样的:

    module d_ff(
            input d,
            input clk,
            input reset,
            input we,
            output q
    );

    always @(posedge clk) begin
            if (~reset) begin
                    q <= 1'b0;
            end
            else if (we) begin
                    q <= d;
            end
            else begin
                    q <= q;
            end
    end
    endmodule

声明q &lt;= q;有必要吗?

【问题讨论】:

    标签: verilog


    【解决方案1】:

    语句 q

    不,不是这样,对于 ASIC,它实际上可能会增加面积和功耗。我不确定现代 FPGA 如何处理这个问题。在综合期间,该工具将看到该语句并要求在每个正时钟沿更新 q。如果没有最后的 else 子句,该工具只能在满足给定条件时免费更新 q

    在 ASIC 上,这意味着综合工具可以插入时钟门(如果库有时钟门)而不是多路复用器。对于单个 DFF,这实际上可能更糟,因为时钟门通常比多路复用器大得多,但如果 q 是 32 位,那么节省的费用可能非常显着。现代工具可以自动检测使用共享使能的 DFF 数量是否满足特定阈值,然后适当地选择时钟门或多路复用器。

    在这种情况下,该工具需要 3 个多路复用器和额外的路由

    always @(posedge CLK or negedge RESET)
      if(~RESET)
        COUNT <= 0;
      else if(INC)
        COUNT <= COUNT + 1;
      else
        COUNT <= COUNT;
    

    这里的工具对所有 DFF 使用单个时钟门

    always @(posedge CLK or negedge RESET)
      if(~RESET)
        COUNT <= 0;
      else if(INC)
        COUNT <= COUNT + 1;
    

    Images from here

    【讨论】:

    • 这似乎是合成器可以对任何一段代码进行的优化,因为行为是相同的
    • 小心时钟门控。它可能会导致故障。
    【解决方案2】:

    就模拟而言,删除该语句不会改变任何内容,因为 q 应该是 reg 类型(或 SystemVerilog 中的逻辑),并且应该保持其值。

    此外,大多数综合工具应该在这两种情况下生成相同的电路,因为 q 是使用非阻塞分配更新的。也许更好的代码是使用 always_ff 而不是 always(如果您的工具支持它)。这样,编译器将检查 q 是否始终使用非阻塞赋值进行更新,并生成顺序逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多