top of page
Writer's pictureAdam Taylor

MicroZed Chronicles: Clock Switching

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 involved.


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 behavior 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.


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;


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 internal synchronised 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.


Up Coming Book!


Do you want to know more about designing embedded systems from scratch? Check out our upcoming book on creating embedded systems. This book will walk you through all the stages of requirements, architecture, component selection, schematics, layout, and FPGA / software design.


We designed and manufactured the board at the heart of the book!


Learn more about the board (see previous blogs on Bring up, DDR validation, USB, Sensors) and view the schematics here.



All schematics and layout will be made available on a new website soon!

1 comment

1 Comment


Wont the following lines generate meta-stable issues??

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;


sel line & clk_b_reg are not synchronized to clk_a

Like
bottom of page