In short, yes, this is possible.
Since you need to toggle twice in that period, you need to count up to the number of cycles the input clock would do divided by two, between the two clock toggles.
So, you could just replace your 2500000
constant with something else. That something else would likely be 1_199_904
. One nice thing VHDL lets you do is that you can make your numeric literals more legible by introducing underscores where you want stuff to be spaced out.
However, this is AFAIK not the best practice for generating slow "clocks". You probably might want to think of it as triggering events at a longer interval instead. (TODO: explain why.)
See perhaps this answer to learn more.
Basically, what you'd do instead of
slow_stuff: process(clk_50Hz)
begin
if(rising_edge(clk_50Hz)) then
-- your magic that happens every clock period, ie. 50x a second
end if;
end process;
is something like this:
slow_stuff: process(clk_fast)
begin
if(rising_edge(clk_fast) and enable_50Hz) then
-- your magic that happens every enable period, ie. still 50x a second
end if;
end process;
A convenient way of generating these signals may be perhaps something like this:
entity enable_timer is
generic (
divide_by : integer := 5_000_000
);
port (
clk : in std_logic;
srst : in std_logic; -- sync reset
enable : out std_logic
);
end entity enable_timer;
architecture I_took_this_from_stackexchange of enable_timer is
signal counter : integer := 0;
begin
magic: process(clk) is
enable <= '0';
if(rising_edge(clk)) then
if(srst = '1') then
counter <= 0;
elsif(counter >= divide_by) then
counter <= 0;
enable <= '1';
else
counter <= counter + 1;
end if;
end if;
end process;
end architecture I_took_this_from_stackexchange;
You could instantiate this with a generic map
mapping the divide_by
parameter to whatever suits your needs at any particular moment (like 2_399_808
to get your 41.67Hz out of your 100MHz clock), and you'll almost* never have to write this timing's entity's implementation again! Reuse it for all your slow* timings! Amazing, isn't it.
An example for instantiation, for the sake of completeness:
my_awesome_41_67Hz_timer: enable_timer
generic map (count_to => 2_399_808)
port map (
clk => clk_100MHz,
srst => reset, -- or '0' if not used
enable => enable_41_67Hz
);
With a counter like this, you can generate about any frequency with 1-period of your main clock resolution, that is 10ns resolution for your 100MHz clock. So yes, 41.67Hz is doable, with about 0.024% error in this case. You can get this constant by dividing the frequency of the input clock and the output clock and rounding. The error comes from exactly this rounding.
*) The error may not always be this low, for example when the output frequency is much closer to the main clock's frequency, and it does not divide quite cleanly. In those cases you could use a fractional clock divider of some sort. I'll say those are beyond the scope of this answer. :)
I have not actually checked the syntax of the above examples yet, so take them more as a guidance than a straight-up copy-pasta.
One_Hundred_to_Ten_MHz_Clock_Divider
when it doesn't actually output a 10 MHz clock? Do look upgeneric
s to make things like this more obvious and generalizable. Also, in FPGAs, if you want something happen at a slow frequency, you typically don't generate and use slow "clocks" like this; instead you'd use a single clock domain, and you generateenable
signals that are 1 main clock period wide, with tonsa dead time in between, as much as you need. There are good reasons for this, routing and glitches/hazards to name a few. \$\endgroup\$