0 votes
in VHDL by (240 points)

How do you do a clock divider in VHDL? What is an example?

3 Answers

0 votes
by (1.8k points)

VHDL Clock Divider


The purpose of a clock divider is to get the clock frequency that you need for the design. Typically, board oscillators will provide a specific frequency into a part pin that may or may not be the frequency that you need for your design. Many designs need multiple different clock frequencies.

With that said, for clocking, you need to consult the documentation for the part family that you are designing for. As an example, Xilinx provides detailed recommendations on how to handle clocking for each of their FPGA part families.

Here's an example for the Xilinx Ultrascale: https://www.xilinx.com/support/documentation/user_guides/ug572-ultrascale-clocking.pdf

What Xilinx commonly recommends is that you handle clock dividers with their dedicated primitives which includes PLL's and MMCM's. An MMCM is a superset of PLL, so depending on which part you have and the needs of your design will determine which one to use. If you have plenty of resources available and only a few clock needs, use the MMCM.

Xilinx tools will let you go use the clock wizard in their GUI where you can set up exactly what you want by putting in the input clock frequency, whether it's coming from a single ended pin, differential pins, or global buffer.

You can then set what output frequency you want on each of the available output channels. The wizard will then set the multiplier and dividers for the channels to try to achieve the output frequency that you want and even tell you what the actual frequency will be.

The wizard also lets you turn on some advanced features if desired and will tell you specs like jitter performance. After using the GUI, it will generate some output files that you can use like a core in your design where it's handling all of the complex stuff for you. This is the recommended way of doing a clock divider so that your routing and timing performance doesn't run into any issues.

Others might recommend using some logic to divide a clock, but in my personal opinion, this is not recommended for many reasons that is beyond the scope of my answer. You can go research the problems associated with gating a clock if you want to explore more.

Stick to the recommendation above and you will avoid numerous problems.

Best Practices

1. Read the recommendation in the clocking documenation for your part family.

2. Use the recommended tool wizards provided by the manufacturer of your part.

3. Try to avoid using logic to generate a clock when you have dedicated part primitives available that can be used correctly with the tool wizard.
0 votes
by (500 points)

Clock division can be achieved using a counter. Example :

signal clock_out : std_logic ; -- clock_out will be a divided version of INPUT_CLOCK. The devision ratio will depend on the length of the counter.
signal counter : unsigned ( 3 downto 0 ) ;

process ( INPUT_CLOCK ) is
if rising_edge ( INPUT_CLOCK ) then
if counter = "1111" then
counter <= ( others => '0' ) ;
clock_out <= not clock_out ;
counter <= counter + 1 ;
end if ;
end if ;
end process ;
0 votes
by (500 points)

The best way for a FPGA design is to use PLLs or MMCM (Xilinx) if possible. You must place it's instances in your rtl.

You can do it manually with code, like with a counter. Here's an example:

process (clk_p) is
if rising_edge(clk_p) then
reload <= '0';
if b_cnt = to_unsigned(1, b_cnt'size) then
reload <= '1';
end if;
if reload='1' then
b_cnt<=b_cnt - 1;
end if;
if nclr_i = '0' then
b_cnt <= (others => '0');
end if;
end if;
end process;

clk_out <= reload;
or you can do it asynchronous if you want:
reload <= '1' when b_cnt = to_unsigned(0, b_cnt'size) else '0';

div2 example:
process (clk_p) is
if rising_edge(clk_p) then
div2 <= not div2;
end if;
end process;
clk_out <= div2;
In FPGA design You will need to define such generated clocks as either global or regional. There are several vendor dependant means to do that: explicit use of clock buffers (in Xilinx), ALTCLKCTRL (in Altera/Intel) and so on.
Hardware Coder Community

© 2022 by Hardware Coder. User contributions are licensed under cc by-sa 4.0 with attribution required. Attribution means a link to the question, answer, user, etc on this site.

This site is owned and operated by Hardware Coder in McKinney, Texas.

Send Us A Message
About Us

By using this site, you agree to the following:

Privacy Policy
Terms and Conditions
DMCA Policy
Earnings Disclaimer
Legal Disclaimer