Clock Divider

Discussion in 'VHDL' started by Mohammed A khader, Mar 10, 2005.

  1. 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.
     
    Mohammed A khader, Mar 10, 2005
    #1
    1. Advertising

  2. Mohammed  A khader

    Neo Guest

    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, Mar 11, 2005
    #2
    1. Advertising

  3. 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
     
    Ralf Hildebrandt, Mar 11, 2005
    #3
  4. 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.
    >
     
    Christian Schneider, Mar 11, 2005
    #4
  5. Mohammed  A khader

    Guest

    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;
     
    , Mar 14, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    644
  2. Matt Clement

    MCU clock divider vs. VHDL divider

    Matt Clement, Apr 20, 2006, in forum: VHDL
    Replies:
    3
    Views:
    4,241
    Marcus Harnisch
    Apr 28, 2006
  3. clock divider by 2

    , Aug 15, 2006, in forum: VHDL
    Replies:
    3
    Views:
    14,693
    arant
    Aug 16, 2006
  4. FP

    clock divider

    FP, Jun 2, 2008, in forum: VHDL
    Replies:
    1
    Views:
    609
  5. oppenheimer

    Clock divider?

    oppenheimer, Jun 7, 2008, in forum: VHDL
    Replies:
    2
    Views:
    1,398
    oppenheimer
    Jun 8, 2008
Loading...

Share This Page