Normally, we clock the logic within our FPGA design using clocks either provided externally or generated internally using MMCMs, PLLs, or other logic structures, e.g., counters. Using these internal or external clocks ensures we know the frequency, tolerance, and, of course, jitter.
However, there are instances when we might want to use the configuration clock in our designs. The configuration clock provides the clock for the configuration of the device when operating in master mode, unless an external configuration clock is provided.
The configuration clock is generated internally within the FPGA using a ring oscillator. As such, it is not really suitable for most applications, as they require a stable clock and a known clock frequency.
The nominal frequency of the clock is stated within the relevant datasheet. For the Spartan 7, it is 100MHz; however, it has a tolerance of ±50%. The configuration clock frequency will vary with process, voltage, and temperature. As such, we cannot use it for things where we need to know the exact frequency.
Normally, this configuration clock is not accessible to the user logic design; however, if desired, we can access the configuration clock in the user logic.
We access this configuration clock in the user logic by using the STARTUP2E primitive in 7-series devices and STARTUPE3 primitives in the UltraScale and UltraScale+ families.
If we want to instantiate the primitive within our FPGA, we can use the template provided by the language templates in the Vivado editor or those defined within the family's library guides (e.g., UG953 for 7-series or UG974 for UltraScale or UltraScale+ families).
STARTUPE2_inst : STARTUPE2
generic map (
PROG_USR => "FALSE", -- Activate program event security feature. Requires encrypted bitstreams.
SIM_CCLK_FREQ => 0.0 -- Set the Configuration Clock Frequency(ns) for simulation.
)
port map (
CFGCLK => CFGCLK, -- 1-bit output: Configuration main clock output
CFGMCLK => CFGMCLK, -- 1-bit output: Configuration internal oscillator clock output
EOS => EOS, -- 1-bit output: Active high output signal indicating the End Of Startup.
PREQ => PREQ, -- 1-bit output: PROGRAM request to fabric output
CLK => CLK, -- 1-bit input: User start-up clock input
GSR => GSR, -- 1-bit input: Global Set/Reset input (GSR cannot be used for the port name)
GTS => GTS, -- 1-bit input: Global 3-state input (GTS cannot be used for the port name)
KEYCLEARB => KEYCLEARB, -- 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
PACK => PACK, -- 1-bit input: PROGRAM acknowledge input
USRCCLKO => USRCCLKO, -- 1-bit input: User CCLK input
-- For Zynq-7000 devices, this input must be tied to GND
USRCCLKTS => USRCCLKTS, -- 1-bit input: User CCLK 3-state enable input
-- For Zynq-7000 devices, this input must be tied to VCC
USRDONEO => USRDONEO, -- 1-bit input: User DONE pin output control
USRDONETS => USRDONETS -- 1-bit input: User DONE 3-state enable output
);
Having accessed the configuration clock, what is it useful for? One of the things I have used it for in previous projects has been to help me select between primary and redundant clocks being input into a device.
In this instance, I used the configuration clock to clock a glitch filter on the clock selection input to ensure there were no glitches or noise on the clock selection input.
I also used it to generate a reset signal, which can be later synchronised with the selected clock to reset the downstream logic.
This approach ensures the glitch filter is being clocked independently and will not be impacted by changes in the clock.
We can also use the configuration clock to detect if one of the clocks is missing or stopped. However, we will not be able to easily or accurately determine the frequency of the clock being monitored.
It is possible, however, to detect whether the monitored clocks are incrementing and have not stopped.
The RTL to create the above system can be seen below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity int_ext_clk is
Port (
clk_ext : in std_logic;
clk_select : in std_logic;
led_sel : out std_logic;
led_clk : out std_logic;
clk_op : out std_logic
);
end int_ext_clk;
architecture Behavioral of int_ext_clk is
signal s_delay_line : std_ulogic_vector(7 downto 0);
signal s_delay_and : std_ulogic;
signal s_delay_nor : std_ulogic;
signal s_output_clean : std_ulogic;
signal s_cclk : std_ulogic;
begin
STARTUPE2_inst : STARTUPE2
generic map (
PROG_USR => "FALSE",
SIM_CCLK_FREQ => 10.0
)
port map (
CFGCLK => open,
CFGMCLK => s_cclk,
EOS => open,
PREQ => open,
CLK => '0',
GSR => '0',
GTS => '0',
KEYCLEARB => '0',
PACK => '0',
USRCCLKO => '0',
USRCCLKTS => '0',
USRDONEO => '1', -- 1-bit input: User DONE pin output control
USRDONETS => '1' -- 1-bit input: User DONE 3-state enable outpu
);
BUFGMUX_inst : BUFGMUX
port map (
O => clk_op, -- 1-bit output: Clock output
I0 => s_cclk, -- 1-bit input: Clock input (S=0)
I1 => clk_ext, -- 1-bit input: Clock input (S=1)
S => s_output_clean -- 1-bit input: Clock select
);
--*** switch interface
--Delay disctete using delay line
synchroniser_process : process (s_cclk) begin
if rising_edge(s_cclk) then
s_delay_line <= s_delay_line(6 downto 0) &
clk_select;
end if;
end process;
--Generate AND and NOR of delay line bits
s_delay_and <= '1' when to_01(s_delay_line) =
(s_delay_line'range => '1') else '0';
s_delay_nor <= '1' when to_01(s_delay_line) =
(s_delay_line'range => '0') else '0';
--Set discrete based on delay line
output_process : process (s_cclk) begin
if rising_edge(s_cclk) then
if s_delay_nor = '1' then
s_output_clean <= '0';
elsif s_delay_and = '1' then
s_output_clean <= '1';
end if;
end if;
end process;
led_sel <= s_output_clean;
end Behavioral;
While not one of the more often-used approaches, it can be useful to understand how we can access the configuration clock and a few of the approaches we might want to use it for.
Workshops and Webinars
If you enjoyed the blog why not take a look at the free webinars, workshops and training courses we have created over the years. Highlights include
Upcoming Webinars Timing, RTL Creation, FPGA Math and Mixed Signal
Professional PYNQ Learn how to use PYNQ in your developments
Introduction to Vivado learn how to use AMD Vivado
Ultra96, MiniZed & ZU1 three day course looking at HW, SW and PetaLinux
Arty Z7-20 Class looking at HW, SW and PetaLinux
Mastering MicroBlaze learn how to create MicroBlaze solutions
HLS Hero Workshop learn how to create High Level Synthesis based solutions
Perfecting Petalinux learn how to create and work with PetaLinux OS
Boards
Get an Adiuvo development board
Adiuvo Spartan 7 / RPi 2040 Embedded System Development Board
Adiuvo Spartan 7 Tile - Low Risk way to add a FPGA to your design.
Embedded System Book
Do you want to know more about designing embedded systems from scratch? Check out our 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! The schematics and layout are available in Altium here Learn more about the board (see previous blogs on Bring up, DDR validation, USB, Sensors) and view the schematics here.
留言