I'm implementing some modules using VHDL and for some of them I need the FPGA's global clock signal, and for some others I need to update to two different frequencies. A common solution to this is using frequency dividers based on counters, so if I have a 8MHz clock and I need 2KHz, I can just count up to 4000 and generate and enable signal for the other components.

But when many clocks are needed, a way of reducing the size for frequency dividers could be cascading them. For example, to generate 2KHz and 1Hz, I could count up to 2000 using the previous generated 2KHz enable signal.

My problem is that, since it's a good practice for scalability and performance the use of a single global clock, using the previous clocks as enable signals causes delays on subsequent clock generation. This is my VHDL code to generate two new clocks based on the global one:

library ieee;
use ieee.std_logic_1164.all;

entity clock_generator is
generic(
global_freq  : integer;
display_freq : integer
);
port(
clk      : in  std_logic;
reset    : in  std_logic;
clk_2KHz : out std_logic;
clk_1min : out std_logic
);
end clock_generator;

architecture behavioral of clock_generator is

constant MAX_2KHz : integer := (global_freq / display_freq) - 1;
constant MAX_1min : integer := (display_freq * 60) - 1;

signal cnt_2KHz : integer range 0 to MAX_2KHz;
signal en_2KHz  : std_logic;

signal cnt_1min : integer range 0 to MAX_1min;

begin

gen_2KHz : process(clk, reset)
begin
if reset = '0' then
cnt_2KHz <= 0;
elsif rising_edge(clk) then
if cnt_2KHz = MAX_2KHz then
cnt_2KHz <= 0;
else
cnt_2KHz <= cnt_2KHz + 1;
end if;
end if;
end process;

en_2KHz <= '1' when cnt_2KHz = MAX_2KHz else '0';

gen_1min : process(clk, reset)
begin
if reset = '0' then
cnt_1min <= 0;
elsif rising_edge(clk) then
if en_2KHz = '1' then
if cnt_1min = MAX_1min then
cnt_1min <= 0;
else
cnt_1min <= cnt_1min + 1;
end if;
end if;
end if;
end process;

clk_2KHz <= en_2KHz;
clk_1min <= '1' when cnt_1min = MAX_1min else '0';

end behavioral;


If I simulate its behavior, we can see that the first clock is generated synchronized with the global one, but since the second depends on the first one's activation, it's delayed one cycle of the global clock:

So my questions are:

1. How can I get full clock synchronization without using individual frequency dividers?
2. Could this synchronization cause any problem on some kind of special systems or is this just negligible?
• "using the previous clocks as enable signals causes delays on subsequent clock generation." That assumption is wrong. In fact they do NOT cause delays as everything changes on the one (master) clock edge signal. In contrast to using the derived signals in subsequent rising_edge(generated_clock) which DOES generate clock skew. – Oldfart Dec 9 '18 at 19:35
• Using a cascade of clock enabled instead of a cascade of "user defined clocks" is the right design approach. The first principle in design is to write a FULLY synchronous design. So every register output is driven by the same clock. The second design principle should be use synchronous resets and the third principle use high-active logic. – Paebbels Dec 9 '18 at 23:22