better way of coding a D flip-flop

2019-01-25 16:43发布

问题:

Recently, I had seen some D flip-flop RTL code in verilog like this:

    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

Does the statement q <= q; necessary?

回答1:

Does the statement q <= q; necessary?

No it isn't, and in the case of an ASIC it may actually increase area and power consumption. I'm not sure how modern FPGAs handle this. During synthesis the tool will see that statement and require that q be updated on every positive clock edge. Without that final else clause the tool is free to only update q whenever the given conditions are met.

On an ASIC this means the synthesis tool may insert a clock gate(provided the library has one) instead of mux. For a single DFF this may actually be worse since a clock gate typically is much larger than a mux but if q is 32 bits then the savings can be very significant. Modern tools can automatically detect if the number of DFFs using a shared enable meets a certain threshold and then choose a clock gate or mux appropriately.

In this case the tool needs 3 muxes plus extra routing

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

Here the tool uses a single clock gate for all DFFs

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

Images from here



回答2:

As far as simulation is concerned, removing that statement should not change anything, since q should be of type reg (or logic in SystemVerilog), and should hold its value.

Also, most synthesis tools should generate the same circuit in both cases since q is updated using a non-blocking assignment. Perhaps a better code would be to use always_ff instead of always (if your tool supports it). This way the compiler will check that q is always updated using a non-blocking assignment and sequential logic is generated.



标签: verilog