Simple generic clock divider generator

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity clock_generator is
  generic(clock_in_speed, clock_out_speed: integer);
  port(
    clock_in: in std_logic;
    clock_out: out std_logic);
end entity clock_generator;

architecture rtl of clock_generator is

  function num_bits(n: natural) return natural is
  begin
    if n > 0 then
      return 1 + num_bits(n / 2);
    else
      return 1;
    end if;
  end num_bits;

  constant max_counter: natural := clock_in_speed / clock_out_speed / 2;
  constant counter_bits: natural := num_bits(max_counter);

  signal counter: unsigned(counter_bits - 1 downto 0) := (others => '0');
  signal clock_signal: std_logic;

begin
  update_counter: process(clock_in)
  begin
    if clock_in'event and clock_in = '1' then
      if counter = max_counter then
        counter <= to_unsigned(0, counter_bits);
        clock_signal <= not clock_signal;
      else
        counter <= counter + 1;
      end if;
    end if;
  end process;
  
  clock_out <= clock_signal;
end architecture rtl;

Usage:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity test is
  port(
    clk_50mhz: in std_logic;
    btn_south: in std_logic;
    led: out std_logic);
end entity test;

architecture rtl of test is
  constant system_speed: natural := 50e6;

  signal clock_10hz: std_logic;

begin
  clock_10hz_generator: entity clock_generator
    generic map(clock_in_speed => system_speed, clock_out_speed => 10)
    port map(
      clock_in => clk_50mhz,
      clock_out => clock_10hz);

  led <= clock_10hz;

end architecture rtl;

29. July 2006, Frank Buß