Clock Divider

M

Mohammed A khader

Guest
Hi ,

I have to design a clock divider. Clock Division Factor is an
unsigned number as an input port(NOT CONSTANT). I could able to think
of an architecture which can divide the clk by even numbers. Here is
the code ....

entity Ad_Clk_Div is
port(
Div_Fac : in unsigned(3 downto 0);-- Division Factor
Clk : in std_logic; -- Global Clk
Reset : in std_logic; -- Global Reset
DClk : out std_logic -- Divided Clk Out
);
end entity Ad_Clk_Div;

architecture Ad_Clk_Div_Arch of Ad_Clk_Div is

signal count : unsigned(3 downto 0);
begin

-- Sequential Process
-- Programmable Load counter and Toggle FiFo
process(Clk,Reset)
begin
if(Reset = '0')then
count <= (others => '0');
DClk <= '0';
elsif(RISING_EDGE(Clk))then
if(count = Div_Fac)then
count <= (others => '0');
DClk <= not DClk ;
else
count <= count + 1 ;
end if;
end if;

end process;
end architecture Ad_Clk_Div_Arch;

How can I make it to divide by odd numbers too... To make it so I
must to detect the falling edges also. Is there any sequential element
/ counter which would work on both the edges .... OR how should I
think to get this funtionality..

Thanks a lot.

Mohammed A Khader.
 
yes, you would have to use the negedge also and club the resulting
outputs appropriately.
Xilinx site has some interesting articles on them. search for clock
dividers in their site.
As far as both edges go, fpgas dont have such dual edge triggered flops.
 
Neo wrote:


As far as both edges go, fpgas dont have such dual edge triggered flops.
But if you really need them, you can use two FFs: one with rising_edge and the other one
with falling_edge and cross-couple their outputs via a XOR-Gate. The XOR-output as to be
taken into account when deciding whether to change a value of one of the flipflops. I call
this thing a "pseudo-dual-edge flipflop".

Remember that with this solution the propagation time increases (XORed output) and setup-
and hold-times are delayed (feedback from output). It is simply not suitable for fully
synchronous desings. ;-)

Ralf
 
If you do not need a duty cycle of 50 percent, and you can come along
with a 66/33 percent duty cycle, then you may considder using a johnson
counter. This is a basically a shift register, which is initiallized
with the "wave form". In your case this may be "110". So your output
signal is 110110110110110110 which has a "clock" period of 1/3 of the
original clock, but a duty cycle of 2/3.

BR,
Chris

Mohammed A khader wrote:
Hi ,

I have to design a clock divider. Clock Division Factor is an
unsigned number as an input port(NOT CONSTANT). I could able to think
of an architecture which can divide the clk by even numbers. Here is
the code ....

entity Ad_Clk_Div is
port(
Div_Fac : in unsigned(3 downto 0);-- Division Factor
Clk : in std_logic; -- Global Clk
Reset : in std_logic; -- Global Reset
DClk : out std_logic -- Divided Clk Out
);
end entity Ad_Clk_Div;

architecture Ad_Clk_Div_Arch of Ad_Clk_Div is

signal count : unsigned(3 downto 0);
begin

-- Sequential Process
-- Programmable Load counter and Toggle FiFo
process(Clk,Reset)
begin
if(Reset = '0')then
count <= (others => '0');
DClk <= '0';
elsif(RISING_EDGE(Clk))then
if(count = Div_Fac)then
count <= (others => '0');
DClk <= not DClk ;
else
count <= count + 1 ;
end if;
end if;

end process;
end architecture Ad_Clk_Div_Arch;

How can I make it to divide by odd numbers too... To make it so I
must to detect the falling edges also. Is there any sequential element
/ counter which would work on both the edges .... OR how should I
think to get this funtionality..

Thanks a lot.

Mohammed A Khader.
 
The divider below will do the job. I know it seems complex, but the
author tried to make it very generic. It does work. The initial
comment header is a mess in this editor, but my attempts to correct it
just made it worse. I did manage to correct the spacing in the actual
code. A straight copy and paste from my text editor to the one in this
forum always results in a spacing mess.

------------------------------------------------------------------------------------------------------
-- clkdiv is from EDN Magazine 8/15/97 Author: Brian Boorman, Harris RF
Communications, Rochester, NY
-- Given a 50% duty cycle input clock, this clock divider will produce
a symmetrical output clock with
-- even or odd clock divsor (n). Corrected error in en_tff1 signal
assignment in generate statement
-- for n even and > 2. Added enable input. Charles M. Elias
------------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
------------------------------------------------------------------------------------------------------
entity clkdiv is
generic(
n: natural
);
port(
clkin : in std_logic; -- 50% Duty Cycle Input
Clock
reset : in std_logic := '0'; -- Active high asynchronous
reset
enable : in std_logic := '1'; -- Active high enable
clkout : out std_logic
);
end clkdiv;

architecture fpga of clkdiv is

-- This subtype will constrain counter width.
subtype divtype is natural range 0 to n - 1;
signal counter : divtype;
signal en_tff1 : std_logic;
signal en_tff2 : std_logic;
signal div1 : std_logic;
signal div2 : std_logic;


begin

assert (n > 1)
report "Clock divisor must be a positive number > 0!" severity
failure;

-- pass clock through, gated low by reset
gOne: if (n = 1) generate
clkout <= clkin when (reset = '0') and (enable = '1') else '0';
end generate;

-- generate a T Flip-Flop
gTwo: if (n = 2) generate
pTwo: process(clkin, reset, div1, enable)
begin
if reset = '1' then
div1 <= '0';
elsif rising_edge(clkin) then
if enable = '1' th
div1 <= not (div1);
else
div1 <= div1;
end if ;
end if;
end process;
clkout <= div1;
end generate;

-- Check if N is odd and greater than 2
gOdd: if (((n/2)*2) = (n - 1)) and (n > 2) generate

pOdd: process(clkin, reset, counter, enable)
begin
if (reset = '1') then
counter <= 0;
elsif rising_edge(clkin) then
if enable = '1' then
if (counter = (n - 1)) then
counter <= 0;
else
counter <= counter + 1;
end if;
else
counter <= counter;
end if ;
end if;
end process;

en_tff1 <= '1' when counter = 0 else '0';
en_tff2 <= '1' when counter = (((n - 1)/2) + 1) else '0';

pOddDiv1: process(clkin, reset, en_tff1, div1, enable)
begin
if (reset = '1') then
div1 <= '1';
elsif rising_edge(clkin) then
if enable = '1' then
if (en_tff1 = '1') then
div1 <= not(div1);
end if;
else
div1 <= div1;
end if ;
end if;
end process;

pOddDiv2: process(clkin, reset, en_tff2, div2, enable)
begin
if (reset = '1') then
div2 <= '1';
elsif falling_edge(clkin) then
if enable = '1' then
if (en_tff2 = '1') then
div2 <= not (div2);
end if;
else
div2 <= div2;
end if ;
end if;
end process;

clkout <= div1 xor div2;
end generate;

-- Check if N is even and greater than 2
gEven: if (((n/2)*2) = n) and (n > 2) generate

pEvenDiv: process(clkin, reset, counter, enable)
begin
if (reset = '1') then
counter <= 0;
elsif rising_edge(clkin) then
if enable = '1' then
if (counter = (n - 1)) then
counter <= 0;
else
counter <= counter + 1;
end if;
else
counter <= counter;
end if ;
end if;
end process;

-- en_tff1 <= '1' when ((counter = 0) or (counter = ((n/2) - 1))) else
-- '0';
en_tff1 <= '1' when (counter = 0) or (counter = (n/2)) else '0';

pEvenDiv1: process(clkin, reset, en_tff1, div1, enable)
begin
if (reset = '1') then
div1 <= '0';
elsif rising_edge(clkin) then
if enable = '1' then
if (en_tff1 = '1') then
div1 <= not (div1);
end if;
else
div1 <= div1;
end if ;
end if;
end process;

clkout <= div1;
end generate;
end fpga;
 

Welcome to EDABoard.com

Sponsor

Back
Top