title: Synchronous reset design in fpga as the limiting factor for timing constraints
body: <p>I've got an fpga design that utilizes synchronous resets (I prefer synchronous resets to asynchronous for reasons discussed elsewhere).  I have four different clock domains in the design and I utilize a single button to generate my reset signal, which is of course totally asynchronous to everything (save my finger).  I debounce the button signal in each of the four clock domains to generate synchronous resets for the four domains from a single source.  My debounce module basically counts N clock cycles of the reset button being asserted.  If more than N cycles have passed with reset asserted then I generate my reset signal (code for this module pasted below).</p>
  
  <p>First question -- are there better ways of generating the reset(s) than this method?</p>
  
  <p>Second (more interesting question): when I look at the timing reports (using xilinx tools) I see that consistently the limiting signals are all reset related.  For example the limiting path is from the reset generator (debouncer) to some state machine's state register.  The reset signals are very high fan out (they touch everything in their respective clock domains).  I'm a little surprised though that my speed is limited by the reset.  I'm finding that I'm limited to something like 8.5 nS where ~50% is routing and ~50% of that is logic.  Any suggestions on how to do this a little better?  How do you go about dealing with synchronous reset generation in fpga designs? </p>
  
  <p>Here's the code for reset generation.  Note that the signal reset signal is akin to the debounced output (e.g. when I instantiate the module the <code>debounced</code> output is the reset for that particular clock domain).</p>
  
  <pre><code>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 &lt;= button;
        b2 &lt;= b1;
     end
  
     /* Debounce the button */
     always @(posedge clk) begin
        if(~b2)
      counter &lt;= 0;
        else if(counter &lt; {log2_NUM_CLKS{1'b1}})
      counter &lt;= counter + 1;
     end
  
     /* Assign the output */
     //wire [WIDTH-1:0] debounced = counter &gt; NUM_CLKS_HIGH;
     reg [WIDTH-1:0] debounced;
  
     always @(posedge clk) begin
        debounced &lt;= counter &gt; NUM_CLKS_HIGH;
     end
  
  endmodule //button_debouncer
  </code></pre>