Most developers use BUFGCTRL or BUFGMUX for clock switching, which can provide glitch-free output on clock switching. However, it pays to understand the principles involved.
Of course, no matter which technique we use in synchronization logic, it is important to ensure that there are no glitches on the output when clock switching occurs. Any failure may cause errors in downstream logic.
So, let’s see how to produce glitch-free output clock switching using only logic gates and registers. Master Peter introduced the following circuit.
Two registers are used to store the status of the select signal. These states are updated on the falling edge of the clock, and deselected registers hold their clocks in reset. Due to the falling edge, the clock is low and the output clock remains low. It will remain low until the selected clock goes low (to update its control register) and goes high.
Achieving this in Vivado is easy. Clock switching can be created with just a few lines of code.
library ieee;
use ieee.std_logic_1164.all;
entity clk_sw is port(
clk_a : in std_logic;
clk_b : in std_logic;
sel : in std_logic;
clk_out : out std_logic);
end entity;
architecture rtl of clk_sw is
signal clk_a_reg : std_logic :='0';
signal clk_b_reg : std_logic :='0';
begin
cntrl_a : process(clk_a)
begin
if falling_edge(clk_a) then
clk_a_reg <= (not sel) and (not clk_b_reg);
end if;
end process;
cntrl_b : process(clk_b)
begin
if falling_edge(clk_b) then
clk_b_reg <= sel and (not clk_a_reg);
end if;
end process;
clk_out <= (clk_a_reg and clk_a) or (clk_b_reg and clk_b);
end architecture;
A PLL is used to divide the system's clock (100MHz) into two random and uncorrelated frequencies. The output clock is brought out to the GPIO pin.
Use the XPM synchronizer macro at 100 MHz to debounce it. The output of the XPM macro is used to switch clocks and route to GPIO pins.
A simple testbench was created that can run simulations in timing simulation to determine if there are faults in the implementation.
In the above figure you can see that no faults were observed in the timing simulation.
The next step is to program the board and observe if there are glitches in the device when the design is implemented in hardware.
Set the frequencies to 6.25 MHz and 8.125 MHz. By default, when the select input is low, an 8.125 MHz clock is output. Switching it high switches the output to a 6.25 MHz clock.
Of course, we need to be able to determine if there are any glitches on the output when the switch occurs. Therefore, use an oscilloscope to monitor the internal sync select signal and clock output pin.
When observing the output clock below, it can be seen that no glitches are observed on the output clock line when the select line of the clock is changed.
Although modern FPGAs contain more advanced and powerful clock management and clock circuits, these circuits do not exist on some low-end FPGAs, and we need to create the clock switching circuits ourselves.