This article discusses how to create a clock divider in VHDL using the counter method. A clock divider is also known as a frequency divider. I also provide the source code for a simple and configurable clock divider implementation.
A clock divider takes an input clock with a given frequency and produces an output clock with some lower, divided frequency.
The first thing that needs to be determined is the scaling factor. The scaling factor is simply the ratio of the input clock frequency and the desired output clock frequency. For this article, the scaling factor will be abbreviated as the variable N.
N represents the number of input clock cycles needed for one output clock cycle. In other words, for every N cycles on the input clock, one cycle on the output clock is generated. Remember that a clock signal is a square wave with a 50% duty cycle. This means that, in one cycle, half of the time is spent high (active) and half of the time is spent low (inactive). Therefore, for a scaling factor of N, the output clock will be set high for N/2 input clock cycles and set low for N/2 input clock cycles.
A clock divider implementation therefore involves using a counter to count to N/2 cycles on the input clock. Once it hits N/2, it toggles the output clock and resets the counter. Note that N must be an even integer in order to have a precise clock divider. If N is not an even integer, you can truncate it to the nearest one and in many cases this will still provide a fairly accurate output.
Clock Divider Source Code
entity clock_divider is
N : integer); --Scaling Factor
clk_in : in std_logic,
clk_out : out std_logic;
reset : in std_logic);
architecture behav of clock_divider is
constant COUNT_RANGE : integer := N/2; --Max value for counter
signal counter : integer range 0 to COUNT_RANGE-1 := 0;
--Buffer signal for output clock, to be used internally
signal clk_out_buf : std_logic := '0';
clk_div_logic : process(clk_in, reset)
if (reset = '1') then
counter <= 0;
clk_out <= '0';
clk_out_buf <= '0';
elsif rising_edge(clk_in) then
--Once N/2 input clock cycles have been counted, toggle the output
--and reset the counter. Otherwise, simply increment the counter
if (clk_div_counter = COUNT_RANGE-1) then
clk_out_buf <= not(clk_out_buf);
clk_out <= not(clk_out_buf);
counter <= 0;
counter <= counter+1;