VHDL code for clock divider

A clock divider is used to get a divided version of a clock. Clock dividers are a very important component of digital design, and are used ubiquitously.

VHDL code for a configurable clock divider: Following is the VHDL code for a configurable divider. It can divide by any number with 50% duty cycle. It makes use of a dual edge-triggered decrement counter, with configurable load; thereby enabling it to divide by any number.

Following is the entity and architecture definitions of top module for clock divider. It takes generic parameter max_bits, which puts a limit on the maximum division that can be obtained with the help of this divider. It takes the divide_value as input, the division ratio of output clock with respect to input clock. The output clock is a divided version of input clock depending on the value of divide_value. We have instantiated a component decr_counter, which takes a parameter and counts downto 0 as discussed in further detail below.

-- This module is for a configurable divider that takes value from a counter and toggles the output clock whenever it receives all zero count.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_UNSIGNED.all;

ENTITY configurable_divider IS
    GENERIC (
        MAX_BITS : INTEGER := 10
            );
    PORT (
        in_clk : IN bit;
        rst : IN bit;
        out_clk : OUT bit;
        divide_value : IN bit_vector(MAX_BITS DOWNTO 0)
         );
END ENTITY;

ARCHITECTURE behavioral OF configurable_divider IS
    -- Declaring a component of configurable_decr_counter
    COMPONENT configurable_decr_counter
        GENERIC (
            MAX_BITS : INTEGER := 10
                );
        PORT (
            clk : IN bit;
            rst : IN bit;
            load_count : IN bit_vector (MAX_BITS DOWNTO 0);
            count : OUT bit_vector (MAX_BITS DOWNTO 0)
             );
    END COMPONENT;
    -- signal declarations
    SIGNAL load_count_reg : bit_vector (MAX_BITS DOWNTO 0);
    SIGNAL curr_count_value : bit_vector (MAX_BITS DOWNTO 0);
    signal out_clk_int : bit;
BEGIN
    PROCESS
    BEGIN
        WAIT UNTIL in_clk'EVENT;
            IF to_StdLogicVector(curr_count_value) = 1 THEN
                out_clk_int <= NOT out_clk_int;
            END IF;
    END PROCESS;
    out_clk <= out_clk_int;
    -- Instantiating configurable_decr_counter
    decr_counter : configurable_decr_counter GENERIC MAP (
                                                            MAX_BITS
                                                                      )
                                                          PORT MAP (
                                                            clk => in_clk,
                                                            rst => rst,
                                                            load_count => divide_value,
                                                            count => curr_count_value
                                                                   );

END ARCHITECTURE behavioral;


Given below is the entity and architecture definition of decr_counter module. It keeps on decrementing until it reaches value 0. On reaching zero, it loads itself with a pre-determined value that is provided as an input to the counter from its top module.

-- This is the VHDL code for a configurable dual edge-triggered decrement counter.
library IEEE;

use IEEE.std_logic_1164.all;
use IEEE.std_logic_UNSIGNED.all;

ENTITY configurable_decr_counter IS
    GENERIC (
        MAX_BITS : INTEGER := 10
            );
    -- Port definitions
    PORT (
        clk : IN bit;
        rst : IN bit;
        load_count : IN bit_vector (MAX_BITS DOWNTO 0);
        count : OUT bit_vector (MAX_BITS DOWNTO 0)
         );
END ENTITY;


ARCHITECTURE behavioral OF configurable_decr_counter IS
    SIGNAL count_value : std_logic_vector (MAX_BITS DOWNTO 0);
BEGIN
    PROCESS(clk,rst)
    BEGIN
        IF rst = '1' THEN
            count <= "000000";
            count_value <= "000001";
        ELSIF clk'EVENT THEN
            IF count_value = 1 THEN
                count_value <= to_StdLogicVector(load_count);
            ELSE
                count_value <= count_value - 1;
            END IF;
            count <= to_bitvector(count_value);
        END IF;
    END PROCESS;
END ARCHITECTURE behavioral;


By the way, this code is not synthesizable, although it will simulate perfectly. We have to make a simple modification to the code to make it synthesizable. Any guesses what makes this code not being synthesized by a synthesis tool? Hope you’ve found this post useful. Let us know what you think in the comments.

Also read:



No comments:

Post a Comment

Thanks for your valuable inputs/feedbacks. :-)