# Synchronous reset in multi clock FPGA design

I want to start using sync reset inside my FPGA designs, and I'm new to Xilinx FPGA design.

Normally I have 5-6 clocks in every design, and the reset is driven from the push button on the board.

What is a good practice to use this asynchronous signal coming to my FPGA as synchronous reset to all the clocks in my FPGA design?

The thing I thought about is just to sync the same async push-button signal with every clock on the board in parallel, like the block diagram I draw here:

The top-level code for clocks and reset generation:

timescale 1 ns / 1 ps

module top_test1 (

input  wire       clk_200mhz_p,     // external clock 200 MHz - p
input  wire       clk_200mhz_n,     // external clock 200 MHz - n
input  wire       reset             // reset push button
);

//*--------------------------------
//* Clock and reset
//*--------------------------------
// Internal 200 MHz clock - System
wire clk_200mhz_ibufg;  // internal 200 MHz clock
wire rst_200mhz_int;    // internal 200 MHz synchronous reset

// Internal 125 MHz clock - Ethernet
wire clk_mmcm_out;      // mmcm clk out - 125 MHz
wire clk_125mhz_int;    // internal 125 MHz clock
wire rst_125mhz_int;    // internal 125 MHz synchronous reset

// Internal 50 MHz clock - DSP
wire clk_bufr_out_50mhz;    // bufr 50mhz clock -> 200 MHz / 4 = 50 MHz
wire clk_50mhz_int;         // internal 50 MHz clk
wire rst_50mhz_int;         // internal 50 MHz synchronous reset

wire mmcm_rst = reset;
wire mmcm_locked;
wire mmcm_clkfb;

IBUFGDS
clk_200mhz_ibufgds_inst(
.I    (clk_200mhz_p),
.IB   (clk_200mhz_n),
.O    (clk_200mhz_ibufg)
);

sync_reset #(
.N        (4)
)
sync_reset_inst_200mhz (
.clk    (clk_200mhz_ibufg),
.rst    (reset),
.out    (rst_200mhz_int)
);

MMCME2_BASE #(
.BANDWIDTH           ("OPTIMIZED"),
.CLKOUT0_DIVIDE_F    (8),
.CLKOUT0_DUTY_CYCLE  (0.5),
.CLKOUT0_PHASE       (0),
.CLKOUT1_DIVIDE      (8),
.CLKOUT1_DUTY_CYCLE  (0.5),
.CLKOUT1_PHASE       (0),
.CLKOUT2_DIVIDE      (1),
.CLKOUT2_DUTY_CYCLE  (0.5),
.CLKOUT2_PHASE       (0),
.CLKOUT3_DIVIDE      (1),
.CLKOUT3_DUTY_CYCLE  (0.5),
.CLKOUT3_PHASE       (0),
.CLKOUT4_DIVIDE      (1),
.CLKOUT4_DUTY_CYCLE  (0.5),
.CLKOUT4_PHASE       (0),
.CLKOUT5_DIVIDE      (1),
.CLKOUT5_DUTY_CYCLE  (0.5),
.CLKOUT5_PHASE       (0),
.CLKOUT6_DIVIDE      (1),
.CLKOUT6_DUTY_CYCLE  (0.5),
.CLKOUT6_PHASE       (0),
.CLKFBOUT_MULT_F     (5),
.CLKFBOUT_PHASE      (0),
.DIVCLK_DIVIDE       (1),
.REF_JITTER1         (0.010),
.CLKIN1_PERIOD       (5.0),
.STARTUP_WAIT        ("FALSE"),
)
clk_mmcm_inst (
.CLKIN1              (clk_200mhz_ibufg),
.CLKFBIN             (mmcm_clkfb),
.RST                 (mmcm_rst),
.PWRDWN              (1'b0),
.CLKOUT0             (clk_mmcm_out),
.CLKOUT0B            (),
.CLKOUT1             (),
.CLKOUT1B            (),
.CLKOUT2             (),
.CLKOUT2B            (),
.CLKOUT3             (),
.CLKOUT3B            (),
.CLKOUT4             (),
.CLKOUT5             (),
.CLKOUT6             (),
.CLKFBOUT            (mmcm_clkfb),
.CLKFBOUTB           (),
.LOCKED              (mmcm_locked)
);

BUFG clk_bufg_inst_125mhz (
.I    (clk_mmcm_out),
.O    (clk_125mhz_int)
);

sync_reset #(
.N        (4)
)
sync_reset_inst_125mhz (
.clk    (clk_125mhz_int),
.rst    (reset),
.out    (rst_125mhz_int)
);

BUFR #(
.BUFR_DIVIDE("4"),      // Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"
.SIM_DEVICE("7SERIES")  // Must be set to "7SERIES"
)
BUFR_inst_50mhz (
.O      (clk_bufr_out_50mhz),   // Clock output port
.CE     (1'b1),                 // Active high, clock enable (Divided modes only)
.CLR    (rst_int),              // Active high, asynchronous clear (Divided modes only)
.I      (clk_200mhz_ibufg)      // Clock buffer input..
// ..driven by an IBUF, MMCM or local interconnect
);

BUFG clk_bufg_inst_50mhz (
.I    (clk_bufr_out_50mhz),
.O    (clk_50mhz_int)
);

sync_reset #(
.N        (4)
)
sync_reset_inst_50mhz (
.clk    (clk_50mhz_int),
.rst    (reset),
.out    (rst_50mhz_int)
);

endmodule
`

The "sync_reset" module is just a pipeline of N registers. So is it a good way to produce all the sync resets I need for my design?

I just want to be sure.

• You probably want to build something which controls reset to everything else. In particular beware that for any DLL sourced clocks you need to hold the clocked logic in reset until the clock is good - otherwise you might see surprising results, for example FPGA "ROM" can see contents corrupted if read timing is violated! Nov 11, 2020 at 15:35

It looks fine. Normally a 2-flop synchronizer is enough for the clock frequencies you target. That's what I have used with push button resets on FPGA boards. But a 4-flop synchronizer still gives better MTBF. Since your design uses synchronous reset, both assertion and release of "push button asynchronous reset" have to be, and will be synchronised by this chain of flip-flops to the respective clock domains.

Since you have designed a synchronizer chain of your own, it's advisable to specify ASYNC_REG (page no. 9 in the document) property on the destination flops. Vivado says -

Specifying ASYNC_REG also affects optimization, placement, and routing to improve Mean Time Before Failure (MTBF) for registers that may go metastable. If ASYNC_REG is applied, the placer will ensure the flip-flops on a synchronization chain are placed closely to maximize MTBF

You can also consider adding a debouncer on the path to avoid erroneous resets. So that your circuit doesn't reset if the reset pulse width is not "long enough", say four clock cycles.

Example:

The upper one is for an active-low reset.

The lower one is for an active-high reset.

• There’s a library element that does this. See my answer. Nov 11, 2020 at 16:41

In general, you will want the reset release to be synchronized with the block’s clock. You also want to ensure that there actually is a running clock when that occurs, and that it’s been running long enough for the reset to have fully taken effect.

The Xilinx library includes a configurable reset block that will handle that for you. Link: https://www.xilinx.com/products/intellectual-property/proc_sys_reset.html

• You bring up a good point here. What do you mean with "long enough"? Enough for the reset to ripple through non-reset pipeline stages? For the PLL to be stable (stable clock period)....? (one requires a counter, the other a lock signal etc...) Aug 23, 2021 at 18:31
• Both PLL stable, and long enough after that for any sync resets to ripple through. Aug 23, 2021 at 18:46
• Thanks, and would you consider the lock/stable signal synchronous or asynchronous? Some manuals claim their device's lock output is synchronized to one of the clocks, yet it turns out it can still chatter... Aug 23, 2021 at 19:12
• I would consider a lock stable to be asynchronous, and would itself need to be resynchronized into the target domain. Aug 23, 2021 at 19:14
• Agreed. Thanks. Do you mind if I edit your comments into the answer? Or, you could of course do it yourself, as it's valuable input. Aug 23, 2021 at 19:23

Here is an example from an FPGA design with two clock domains. One is a 33 MHz PCI interface & associated circuits, and the other is for a 50 MHz block. Note - the key here, like others have said, is to release the reset synchronously wrt the domain clock.

• Actually OP uses synchronous reset in his design, but the push button reset he set on the board is an asynchronous signal. So BOTH assertion as well as release of that "asynchronous reset" has to be synchronised to the clock. If the OP were using asynchronous reset in his design, then only release has to be synchronised. Nov 12, 2020 at 2:37
• Where would you "and" it with the PLL lock / clock stable signal? Before the RST / _RST_N inputs or after the creset outputs? Aug 23, 2021 at 18:34

Ideally a reset initializes asynchronously by a “debounced” active low state and then remains in this state until released which is synchronized to the system clock with a single flip flop.

The release is not just mechanical, but held low by a capacitor whose RC time constant is longer that the bounce time of an old worn out button switch or 15 ms or more into a Schmitt trigger.

• button switches are expected to bounce in the 1~5 ms range and 1 A toggle switches 10~25 ms.

: recommendation

• all you need is a cap, a Schmitt trigger gate, and a D FF, system clock with a button switch to ground and of course your 10 kΩ to 1 MΩ pull-up.

Got it?

• The idea is that the first button contact charges and holds the Reset low voltage and if the release bounces, the capacitor stays low anyway long enough to prevent multiple edges.

• Just make sure you have a “state” controlled reset in your design and not “edge” controlled unless that circuit self synchronizes or does not need to be in sync.

Do I need to draw this?

• This does not answer the question, which is about how to deal with this within a multi-clocked FPGA design. Nov 12, 2020 at 1:00
• All the clocks are synchronous in frequency but may vary in latency. So my answer still holds true. You synchronize all clocks to 1 master clock reset removal. So I disagree strongly @Graham Nov 15, 2020 at 17:42