Editor’s Note: This content is republished from the MicroZed Chronicles, with permission from the author.
Last week we examined several techniques for generating non-integer clock divisions in our FPGA if no PLL was available or we couldn’t use one for that development. This week, we are going to look at another of Peter’s circuits that provides clock switching between two clocks without a glitch on the output.
For most developments, we would use a BUFGCTRL or BUFGMUX which provides glitch-less outputs on the clock. However, as one of the LinkedIn comments on last week’s post reminded me, it is good to understand the principals.
Of course, regardless of the technique we use in synchronous logic, it is important to ensure that there are no glitches on the output when doing clock switching. Any glitches could result in incorrect behaviour of the logic downstream.
So, lets look at how can we do clock switching that produces a glitch-less output using only logic gates and registers. The circuit Peter presented can be seen below. It is amazingly simple that two registers are used to store the status of the select signal. These are updated on the falling edge of the clock and the deselected registers holds its clock in reset. The clock is low due to the falling edge and the output clock stays low. It will remain low until the selected clock has gone low (to update its control register) and high.
Implementing this in Vivado is simple. Only a few lines of code are required to create the switching structure.
entity clk_sw is port(
clk_a : in std_logic;
clk_b : in std_logic;
sel : in std_logic;
clk_out : out std_logic);
architecture rtl of clk_sw is
signal clk_a_reg : std_logic :='0';
signal clk_b_reg : std_logic :='0';
cntrl_a : process(clk_a)
if falling_edge(clk_a) then
clk_a_reg <= (not sel) and (not clk_b_reg);
cntrl_b : process(clk_b)
if falling_edge(clk_b) then
clk_b_reg <= sel and (not clk_a_reg);
clk_out <= (clk_a_reg and clk_a) or (clk_b_reg and clk_b);
I used a Basys 3 Artix-7 FPGA development board to test the switching and divided the clock on the board (100MHz) down to two random and non-related frequencies using a clocking wizard. The output clock was routed to the PMod JA pin 1.
For the selection of the clock, I used SW0. I used the XPM synchronizer macro at 100 MHz to debounce it. The output of the XPM macro was used to switch the clocks and routed to Pmod JA pin 2.
After implementing the design and generating the bitstream, I created a simple test bench that could be run in a timing simulation to determine if there were any glitches in the implementation.
No glitches were observed in the post implementation timing simulation.
The next step was to program the board and observe if there were any glitches in the device when the design was implemented in the hardware.
I had set the frequencies at 6.25 Mhz and 8.125 MHz. The 8.125 MHz clock will be output when the select input is low by default. Switching it to high will result in the output being switched to the 6.25 MHz clock.
Of course, we need to be able to determine if there are any glitches on the output when the switching occurs. For this reason, I use the internally select signal routed to the Pmod JA pin 2.
It is this signal that I will use to trigger the oscilloscope to detect any glitches on the clock output signal when the clock switches.
As can be seen below when observing the output clock, there were no glitches observed on the output clock line when the select line for the clocks was changed.
The circuits we have looked at over the last two weeks are very elegant. Though modern FPGAs contain more advanced and capable clock managers and clocking circuits, we have a good understanding of how these can be created if required.