更好的编码D触发器的方法

e19*_*001 7 verilog

最近,我在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
Run Code Online (Sandbox Code Playgroud)

该声明是否q <= q;必要?

小智 7

声明q <= q; 必要?

不,它不是,并且在ASIC的情况下,它实际上可能增加面积和功耗.我不确定现代FPGA如何处理这个问题.在综合期间,该工具将看到该语句并要求在每个正时钟边沿更新q.如果没有最终的else子句,q只要满足给定条件,该工具就可以自由更新.

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

用最后的else子句

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

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

没有最终的else子句

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

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

来自这里的图片