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"),
.CLKOUT4_CASCADE ("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.