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.

#### Scaling factor

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity clock_divider is generic ( N : integer); --Scaling Factor port ( clk_in : in std_logic, clk_out : out std_logic; reset : in std_logic); end clock_divider; architecture behav of clock_divider is --Counter 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'; begin clk_div_logic : process(clk_in, reset) begin 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; else counter <= counter+1; end if; end if; end process; end behav; |