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: